/**
 * 数组对象扩展方法
 * update time:2019年10月21日 14:28:51
 */
export class ArrayExtands<T> extends Array {
  /**
   * 数组分组
   *
   * @param array origin array.
   * @param compute diff function
   *
   * @description If the comparison result is true, then the two are in a group.
   *
   * @returns Grouped 2D array
   *
   */
  groupBy(compute: (a: T, b: T) => boolean): Array<Array<T>> {
    let r = new Array<Array<T>>(0);
    let array = this;
    let db = (
      r: Array<Array<T>>,
      n: T,
      compute: (a: T, b: T) => boolean,
      index: number = 0
    ): number => {
      if (r[index] && compute(n, r[index][0])) return index;
      else if (r.length > index) return db(r, n, compute, index + 1);
      else return -1;
    };
    for (let n = 0, lastIndex = 0; n < array.length; n++) {
      let a = array[n];
      if (r.length == 0) {
        r.push([a]);
      } else {
        let index = db(r, a, compute, lastIndex);
        if (index === -1) {
          r.push([a]);
          lastIndex = 0;
        } else {
          r[index].push(a);
          lastIndex = index;
        }
      }
    }
    return r;
  }
  /**
   * 异步forEach
   * @description 无聊的写法(正常可以通过 for of 循环实现.此处用来凑数)
   * @param callback
   */
  async asyncForEach(callback: (item: T, index: number) => void) {
    for (let n = 0, len = this.length; n < len; n++) {
      await callback(this[n], n);
    }
  }
}
/* add extands to Array.prototype */
Object.assign(Array.prototype, new ArrayExtands());
